package com.shop.shopcommon.utils;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.xcontent.XContentType;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.shop.shopcommon.constant.MessageConstant.INDEX_EXISTS;
import static com.shop.shopcommon.constant.MessageConstant.INDEX_NOT_EXISTS;


@RequiredArgsConstructor
@Slf4j
@Component
public class ElasticsearchOperate {

    private final RestHighLevelClient client;
    private final ObjectMapper objectMapper;

    /**
     * 请求分词并返回分词后数组
     * @param ikType
     * @param searchText
     */
    public List<String> applyWordSegment(String ikType, String searchText) throws Exception{
        // 构建请求体的 Map
        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("analyzer", ikType);
        requestBody.put("text", searchText);

        // 将 Map 转换为 JSON 字符串
        String jsonBody = objectMapper.writeValueAsString(requestBody);

        // 创建一个 HTTP POST 请求
        Request request = new Request("POST", "/_analyze");
        request.setJsonEntity(jsonBody);

        // 设置请求选项
        RequestOptions.Builder optionsBuilder = RequestOptions.DEFAULT.toBuilder();
        request.setOptions(optionsBuilder);

        // 执行请求
        Response response = client.getLowLevelClient().performRequest(request);

        // 返回响应体
        java.io.InputStream content = response.getEntity().getContent();
        java.util.Scanner scanner = new java.util.Scanner(content).useDelimiter("\\A");
        String responseBody = scanner.hasNext() ? scanner.next() : "";
        // 判断响应体是否为空
        if (responseBody == null || responseBody.isEmpty()) {
            // 响应体为空，返回空
            return null;
        }
        log.info("响应体: " + responseBody);

        // 用于存储所有 token 值的列表
        List<String> tokenValues = new ArrayList<>();
        try {
            // 解析 JSON 字符串为 JsonNode
            JsonNode rootNode = objectMapper.readTree(responseBody);
            // 获取 tokens 数组
            JsonNode tokensNode = rootNode.get("tokens");
            // 遍历 tokens 数组
            for (JsonNode tokenNode : tokensNode) {
                // 获取 token 值
                String token = tokenNode.get("token").asText();
                tokenValues.add(token);
            }
            // 输出所有 token 值
            for (String token : tokenValues) {
                log.info("分词结果："+token);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return tokenValues;
    }

    /**
     * 判断索引是否存在
     * @param indexName
     * @throws Exception
     */
    public Boolean isExistsIndex (String indexName) throws Exception{
        if (client.indices().exists(new GetIndexRequest(indexName),RequestOptions.DEFAULT)) {
            log.info(INDEX_EXISTS);
            return true;
        } else {
            log.info(INDEX_NOT_EXISTS);
            return false;
        }
    }

    /**
     * 创建索引
     * @param indexName
     * @param mapping
     * @throws Exception
     */
    public void createIndex (String indexName, String mapping) throws Exception{
        CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName)
                .source(mapping, XContentType.JSON);
        client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
    }


    /**
     * 批量全量更新文档-构建BulkRequest
     * @param bulkRequest
     * @param indexName
     * @param id
     * @param Doc
     * @throws Exception
     */
    public void addBulkRequest( BulkRequest bulkRequest,String indexName, String id, String Doc){
        bulkRequest.add(new UpdateRequest(indexName, id)
                // 更新内容
                .doc(Doc,XContentType.JSON)
                // 如果不存在则新增
                .upsert(Doc, XContentType.JSON));
    }

    /**
     * 批量全量更新文档-执行BulkRequest
     * @param bulkRequest
     * @throws Exception
     */
    public void applyBulkRequest(BulkRequest bulkRequest) throws Exception{
        client.bulk(bulkRequest, RequestOptions.DEFAULT);
    }
}
